<?php

namespace Tasker\Models;

class AuthorizationModel extends BaseModel
{

	public function getRoles()
	{
		return $this->connection->user_role()->order('priority');
	}

	public function getRole(array $where)
	{
		return $this->connection->user_role[$where];
	}

	public function getPermissions()
	{
		return $this->connection->user_permission();
	}

	public function getPermission(array $where)
	{
		return $this->connection->user_permission[$where];
	}

	public function getPermissionsInRoles()
	{
		return $this->connection->user_permission_role();
	}

	public function getPermissionsInRolesArray()
	{
		$permissionsInRoles = array();
		foreach ($this->getPermissionsInRoles() as $permissionRole)
		{
			$permissionsInRoles[$permissionRole['user_role_id']][] = $permissionRole['user_permission_id'];
		}
		return $permissionsInRoles;
	}

	public function savePermissions($permissions)
	{
		if (is_array($permissions) || $permissions instanceof \Traversable)
		{
			try
			{
				$this->connection->transaction = 'BEGIN';
				$this->connection->user_permission_role()->delete();
				foreach ($permissions as $role => $perms)
				{
					foreach ($perms as $permission)
					{
						$this->connection->user_permission_role()->insert(array('user_role_id' => $role, 'user_permission_id' => $permission));
					}
				}
				$this->connection->transaction = 'COMMIT';
				return true;
			} catch (\Exception $e)
			{
				$this->connection->transaction = 'ROLLBACK';
				return false;
			}
		}
		return false;
	}

	public function addRole($values)
	{
		$n_values = array(
			'name' => $values['name'],
			'role' => \Nette\Utils\Strings::webalize($values['name']),
			'priority' => $values['priority']+1,
		);
		$affected = $this->connection->user_role()->insert($n_values);
		if ($affected === FALSE)
		{
			return false;
		}else{
			$this->connection->user_role()->where('priority >= '.$n_values['priority'].' AND id <> '.$affected['id'])->update(array('priority' => new \NotORM_Literal('priority+1')));
			return true;
		}
	}

	public function editRole($values)
	{
		$values = (array)$values;
		$role = $this->connection->user_role[$values['id']];
		if ($role['priority'] == $values['priority'] + 1) // not changed
		{
			unset($values['priority']);
			$affected = $this->connection->user_role[$values['id']]->update($values);
		} else // changed
		{
			if($values['priority'] > $role['priority'])
				$values['priority']--;
			$this->connection->user_role()->where('priority > '.$role['priority'])->update(array('priority' => new \NotORM_Literal('priority-1')));
			$this->connection->user_role()->where('priority > '.$values['priority'])->update(array('priority' => new \NotORM_Literal('priority+1')));
			
			$values['priority']++;
			$affected = $this->connection->user_role[$values['id']]->update($values);
		}
		if ($affected === FALSE)
		{
			return false;
		}
		return true;
	}

	public function deleteRole($id)
	{
		$role = $this->connection->user_role[$id];
		$affected = $this->connection->user_role[$id]->delete();
		if ($affected === FALSE)
		{
			return false;
		}else{
			$this->connection->user_role()->where('priority > '.$role['priority'])->update(array('priority' => new \NotORM_Literal('priority-1')));
			return true;
		}
	}

}
